Skip to content

Area of Interest / Fetch Statistics Plugin#93

Open
BhattaraiSijan wants to merge 24 commits into
feat/imapengine-drawingfrom
feat/draw-aoi-plugin
Open

Area of Interest / Fetch Statistics Plugin#93
BhattaraiSijan wants to merge 24 commits into
feat/imapengine-drawingfrom
feat/draw-aoi-plugin

Conversation

@BhattaraiSijan
Copy link
Copy Markdown
Collaborator

@BhattaraiSijan BhattaraiSijan commented May 21, 2026

Purpose

Adds the AOI plugin — pick an area of interest on the map (search / inspect / draw / upload) — and a companion background plugin (FetchStats) that runs per-layer statistics analysis against every visible analysis-supported layer. FetchStats publishes keyed results on the mmgisAPI event bus for downstream consumers (e.g. the Chart plugin) to render.


Proposed Changes

[ADD] src/essence/Tools/AOI/ — draw/select plugin

  • AOITool.js — MMGIS wrapper; only file in the plugin that touches mmgisAPI
  • AOIComponent.tsx + .scss + _aoi-tokens.scss — panel UI (Search / Inspect / Draw / Upload modes + Analyzing progress overlay)
  • AOITooltip.tsx — anchored "Analyze area / Cancel" confirm popover
  • aoiHelpers.ts — pure parse / search / centroid / bounds helpers
  • aoiBoundaryLoader.ts — webpack require.context discovery + lazy fetch + dedup
  • config.json — Configure UI registration

[ADD] src/essence/Tools/FetchStats/ — no-UI background plugin

  • FetchStatsTool.js — subscribes to plugin:aoi:analysisAOIReady, POSTs each visible analysis-supported layer to its stats endpoint in parallel, emits progress + results
  • config.json — Configure UI registration (no panel, auto-initializes via initialize())

[ADD] 54 bundled GeoJSON boundaries

Under src/essence/Tools/AOI/assets/geo-data/states/ (50 states + DC + PR + US + US-contiguous + sample).

[ADD] Bus surface

AOI plugin (auto-prefixed plugin:aoi:)

Direction Event Payload
Emits areaDrawn { feature, source: 'search'|'draw'|'upload'|'inspect', layerName }
Emits analysisAOIReady { feature }
Emits drawingCleared {}
Emits drawingCancelled {}
Provides getCurrentSelection { feature, source } | null
Listens tool:change
Listens map:drawstart / drawvertex / drawcomplete / drawcancel
Listens map:featureClick inspect-mode boundary clicks, filtered by layerId
Listens plugin:fetch-stats:analysisProgress { done, total } — drives progress bar
Listens plugin:fetch-stats:analysisReady { analysisData } — dismisses overlay
Requests map:createLayer / removeLayer
Requests map:fitBounds
Requests map:enableDrawing / finishDrawing / disableDrawing
Requests map:addOverlay / removeOverlay

FetchStats plugin (auto-prefixed plugin:fetch-stats:)

Direction Event Payload
Emits analysisProgress { done: number, total: number }
Emits analysisReady { analysisData: { [layerDisplayName]: <stats response | null> } }
Listens plugin:aoi:analysisAOIReady { feature }
Requests layers:getVisible
Requests layers:getAll
Requests layers:getConfig

[ADD] Map_.js wire-up

One bus wire-up in src/essence/Basics/Map_/Map_.js (4 lines):

engine.onFeatureClick((info) =>
    window.mmgisAPI.emit('map:featureClick', info)
)

Exposes the engine adapter's existing per-feature click handler on the bus so plugin-created vector layers (Inspect-mode boundaries) can receive clicks without going through the standard MMGIS layer pipeline. Engine-agnostic — both LeafletAdapter and DeckGLAdapter already implement onFeatureClick.

[ADD] Per-layer opt-in mission config

"analysis": {
  "is_analysis_supported": true,
  "itemUrl": "https://…/raster/collections/<c>/items/<i>",
  "assets": ["dnbr"],
  "bidx": [1],
  "nodata": -9999
}

[ADD] Dependencies

Runtime: @trussworks/react-uswds, @uswds/uswds, shpjs. Dev: @types/jest, sass.

[NOTE] Mission setup required

Both AOI and FetchStats must be added to the mission's tools list in the Configure page for the full analysis flow to activate.


Issues

Closes #81


Testing

Manually tested on a DeckGL mission with two analysis-supported layers (Sentinel2-Colorir-Daily, Sentinel-2 dNBR):

  • Search → pick a state → tooltip appears at centroid, map fits to bounds, areaDrawn fires with source: 'search'
  • Inspect → click any US state on the map → that state is selected (not the country polygon); areaDrawn fires with source: 'inspect'
  • Draw polygon (≥3 vertices), rectangle (2 corner clicks), circle (centre + edge) → Confirm finalises; drawcomplete flows into selection
  • Upload.geojson, .json, .kml, .zip (shapefile with .shp/.dbf/.prj) → each parses into a selection
  • Analyze area → FetchStats receives analysisAOIReady, discovers visible analysis-supported layers, fires parallel POSTs; progress bar fills via analysisProgress events; overlay dismisses on analysisReady
  • Per-layer failure handling — layers whose /statistics POST returns non-2xx come back as null entries in analysisData; the run still succeeds for other layers
  • Cancel + tool switch — both clear the selection layer and tooltip and emit the appropriate event
  • Chart plugin (PR Adds Chart plugin #94) receives plugin:fetch-stats:analysisReady and renders the results

Tested on macOS, Chrome.


Known follow-ups

  • LeafletAdapter.onFeatureClick uses a bbox picker rather than a true polygon hit-test — works for the DeckGL flow this PR exercises; flagged for the engine branch
  • Chart plugin wired to plugin:fetch-stats:analysisReady is in a separate PR (Adds Chart plugin #94) and must be merged after this one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant